package com.mugui.spring.net.websocket;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.mugui.spring.base.ManagerInterface;
import com.mugui.spring.base.Module;
import com.mugui.spring.net.auto.AutoManager;
import com.mugui.spring.net.classutil.DataSave;

@Component
@AutoManager
public class WebSocketManager implements ManagerInterface<String, Object> {

	private HashMap<String, Object> map = null;

	public void init() {
		if (map == null) {
			synchronized (WebSocketSessionManager.class) {
				if (map == null)
					map = new HashMap<>();
			}
		}
	}

	public Set<Entry<String, Object>> entrySet() {
		return map.entrySet();
	}

	Object serverEndpointExporter = null;

	public boolean isOpenWebSocket() {
		return serverEndpointExporter != null;
	}

	private ApplicationContext applicationContext = null;

	public boolean init(Object name) {
		System.out.println(WebSocketManager.class.getName() + "初始化");
		init();
		clear();
		applicationContext = (ApplicationContext) System.getProperties().get("Application");
		try {
			serverEndpointExporter = applicationContext.getBean("serverEndpointExporter");
		} catch (Exception e) {
		}
		if (!isOpenWebSocket()) {
			return true;
		}

		for (Class<?> class_name : DataSave.initClassList((Class<?>) name)) {
			if (class_name.isAnnotationPresent(WebSocket.class)) {
				System.out.println(WebSocketManager.class.getName() + "初始化->" + class_name.getName());
				WebSocket filter = class_name.getAnnotation(WebSocket.class);
				WebSocketBean webSocketBean = new WebSocketBean(filter, class_name);
				if (StringUtils.isBlank(webSocketBean.getValue())) {
					if (class_name.isAnnotationPresent(Module.class)) {
						Module module = class_name.getAnnotation(Module.class);
						webSocketBean.setValue(module.name() + "." + module.type() + ".*");
					} else {
						webSocketBean.setValue(class_name.getName());
					}
				}
				handleMethod(webSocketBean, class_name);
			}
		}
		return true;
	}

	private void handleMethod(WebSocketBean webSocket, Class<?> class_name) {
		Method[] methods2 = class_name.getDeclaredMethods();
		for (Method method : methods2) {
			System.out.println(
					WebSocketManager.class.getName() + "初始化->" + class_name.getName() + "." + method.getName());
			WebSocketBean webSocketBean = WebSocketBean.newBean(webSocket);
			if (method.isAnnotationPresent(WebSocketMethodConf.class)) {
				WebSocketMethodConf annotation = method.getAnnotation(WebSocketMethodConf.class);
				WebSocketMethodConfBean webSocketMethodConfBean = new WebSocketMethodConfBean(annotation);

				webSocketBean.setConf(webSocketMethodConfBean);
			}
			webSocketBean.setValue(webSocket.getValue().replace(".*", "." + method.getName()));
			handleKey(webSocketBean.getValue(), webSocketBean);
			webSocketTask.createCycleTask(webSocketBean);
		}
	}

	@Autowired
	private WebSocketTask webSocketTask;

	private void handleKey(String key, WebSocketBean object) {
		String keys[] = key.split("[.]");
		Map<String, Object> tempmap = map;
		for (String temp : keys) {
			temp = temp.trim();
			HashMap<String, Object> t = null;
			if ((t = (HashMap<String, Object>) tempmap.get(temp)) == null) {
				t = new HashMap<>();
				tempmap.put(temp, t);
			}
			tempmap = t;
		}
		tempmap.put("&&", object);
	}

	@Override
	public Object get(String name) {
		if (map == null) {
			throw new NullPointerException("please run init");
		}
		HashMap<String, Object> tempmap = map;
		for (String key : name.split("[.]")) {// TODO 如无意外，暂不用修改
			HashMap<String, Object> temp = (HashMap<String, Object>) tempmap.get(key);
			if (temp == null) {
				temp = (HashMap<String, Object>) tempmap.get("*");
			}
			if (temp == null) {
				return null;
			}
			tempmap = temp;
			if (tempmap.size() == 1 && temp.containsKey("&&")) {
				break;
			}
		}
		return tempmap.get("&&");
	}

	/**
	 * 充满疑问的删除操作，是否会发生不可知事件，请劲量不要调用
	 */
	@Override
	@Deprecated
	public Object del(String name) {
		init();
		HashMap<String, Object> tempmap = map;
		for (String key : name.split("[.]")) {// TODO 如无意外，暂不用修改
			HashMap<String, Object> temp = (HashMap<String, Object>) tempmap.get(key);
			if (temp == null) {
				temp = (HashMap<String, Object>) tempmap.get("*");
			}
			if (temp == null) {
				return null;
			}
			tempmap = temp;
			if (tempmap.size() == 1 && temp.containsKey("&&")) {
				break;
			}
		}
		return tempmap.remove(name);
	}

	/**
	 * TODO 该功能暂无需实现，暂无意义
	 */
	@Override
	public boolean add(String name, Object object) {
		init();
		JSONArray array = JSONArray.parseArray(object.toString());
		Iterator<Object> iterator = array.iterator();

		while (iterator.hasNext()) {
			Object next = iterator.next();
			WebSocketBean webSocketBean = WebSocketBean.newBean(WebSocketBean.class, next);
			System.out.println("新加入的处理器：" + webSocketBean.getValue() + " " + webSocketBean);
			handleKey(webSocketBean.getValue(), webSocketBean);
		}
		return true;
	}

	@Override
	public boolean clear() {
		init();
		map.clear();
		return true;
	}

	@Override
	public boolean is(String name) {
		return get(name) != null;
	}

	@Override
	public boolean isInit() {
		// TODO Auto-generated method stub
		return false;
	}

}
